#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

#define MAX_LEN 64
#define PING_PONG_CNT 5

int main(int argc, char *argv[]) {
    pid_t pid;
    int forward[2];
    int backward[2];

    if (pipe(forward) < 0) {
        perror("pipe");
        exit(1);
    }

    if (pipe(backward) < 0) {
        perror("pipe");
        exit(1);
    }

    if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }

    /* parent -> child */
    if (pid == 0) { /* Child process */
        char buf[MAX_LEN];
        
        close(forward[1]);
        close(backward[0]);

        /* read return -1 when encounter error, 0 if all the write fd close, n means read n bytes */
        /* if return > 0, child process has to write the char in buffer back, otherwise means the parent process finish, it doesn't need to listen anymore */
        while (read(forward[0], buf, sizeof(buf)) > 0) {
            write(backward[1], buf, sizeof(buf));
            memset(buf, 0, sizeof(buf));
        }

        close(forward[0]);
        close(backward[1]);
    } else { /* Parent process */
        int i;
        char buf[MAX_LEN], *ping_msg = "from parent";
        
        close(forward[0]);
        close(backward[1]);

        for (i = 0; i < PING_PONG_CNT; i++) {
            printf("ping: %s\n", ping_msg);
            write(forward[1], ping_msg, strlen(ping_msg));
            read(backward[0], buf, sizeof(buf));
            printf("pong: %s\n", buf);
            memset(buf, 0, sizeof(buf));
            sleep(1);
        }
        
        close(forward[1]);
        close(backward[0]);
    }
}